﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Design;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Windows.Forms.Design.Behavior;
using InkFx.WinControl.Core;
using InkFx.WinControl.Design;
using InkFx.WinControl.Theme;
using InkFx.WinControl.Utils;

namespace InkFx.WinControl
{
    /// <summary>
    /// 为可用作其他控件的容器的控件提供焦点管理功能。
    /// </summary>
    //[Designer(typeof(SplitControlDesigner))]
    [ToolboxItem(true), ToolboxBitmap(typeof(SplitControl), "Resources.Toolbox.SplitContainer.png")]
    //[TechSupport("http://ink-fx.com/SDK/InkFx.WinControl/SplitControl/")]
    public class SplitControl : BaseSplitControl
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public SplitControl()
        {
            SetStyle(Win32API.ControlStylesUAORSD, true);

            base.SplitterWidth = 4;
            base.BackColor = Color.Transparent;
            m_LastSplitterDistance = base.SplitterDistance;
        }


        #region  字 段 属 性

        /// <summary>
        /// 内部字段
        /// </summary>
        protected bool m_TLButtonVisible = true;
        /// <summary>
        /// 内部字段
        /// </summary>
        protected bool m_BRButtonVisible = true;

        /// <summary>
        /// 内部字段
        /// </summary>
        protected int m_LastSplitterDistance;
        /// <summary>
        /// 内部字段
        /// </summary>
        protected int m_MinPanel1Size;
        /// <summary>
        /// 内部字段
        /// </summary>
        protected int m_MinPanel2Size;
        /// <summary>
        /// 内部字段
        /// </summary>
        protected readonly object m_TLButtonClickEvent = new object();
        /// <summary>
        /// 内部字段
        /// </summary>
        protected readonly object m_BRButtonClickEvent = new object();
        /// <summary>
        /// 内部字段
        /// </summary>
        protected Splitter.SplitPartType mouseHoverRectType = Splitter.SplitPartType.None;
        /// <summary>
        /// 内部字段
        /// </summary>
        protected Splitter.SplitPartType mouseDownRectType = Splitter.SplitPartType.None;


        /// <summary>
        /// 
        /// </summary>
        [CategorySkinTheme, Browsable(true), Description("当点击 向上或向左 折叠按钮时发生")]
        public event EventHandler TLButtonClick
        {
            add { base.Events.AddHandler(m_TLButtonClickEvent, value); }
            remove { base.Events.RemoveHandler(m_TLButtonClickEvent, value); }
        }
        /// <summary>
        /// 
        /// </summary>
        [CategorySkinTheme, Browsable(true), Description("当点击 向下或向右 折叠按钮时发生")]
        public event EventHandler BRButtonClick
        {
            add { base.Events.AddHandler(m_BRButtonClickEvent, value); }
            remove { base.Events.RemoveHandler(m_BRButtonClickEvent, value); }
        }

        /// <summary>
        /// 是否显示 向上或向左 的 箭头按钮
        /// </summary>
        [CategorySkinTheme, Browsable(true), Description("是否显示 向上或向左 的 箭头按钮")]
        public bool TLButtonVisible
        {
            get { return m_TLButtonVisible; }
            set
            {
                if (m_TLButtonVisible != value)
                {
                    if (!value) base.Panel1Collapsed = false;
                    m_TLButtonVisible = value;
                }
            }
        }
        /// <summary>
        /// 是否显示 向下或向右 的 箭头按钮
        /// </summary>
        [CategorySkinTheme, Browsable(true), Description("是否显示 向下或向右 的 箭头按钮")]
        public bool BRButtonVisible
        {
            get { return m_BRButtonVisible; }
            set
            {
                if (m_BRButtonVisible != value)
                {
                    if (!value) base.Panel2Collapsed = false;
                    m_BRButtonVisible = value;
                }
            }
        }
        /// <summary>
        /// Panel1 是否是展开状态
        /// </summary>
        [CategorySkinTheme, Browsable(false), DefaultValue(true), Description("Panel1 是否是展开状态")]
        public bool Panel1Expanded
        {
            get { return !base.Panel1Collapsed; }
            set { base.Panel1Collapsed = !value; }
        }
        /// <summary>
        /// Panel2 是否是展开状态
        /// </summary>
        [CategorySkinTheme, Browsable(false), DefaultValue(true), Description("Panel2 是否是展开状态")]
        public bool Panel2Expanded
        {
            get { return !base.Panel2Collapsed; }
            set { base.Panel2Collapsed = !value; }
        }
        /// <summary>
        /// 分割线 在折叠 Panel1 或 Panel2 时 最后一次的 分割像素
        /// </summary>
        [CategorySkinTheme, Browsable(false), Description("分割线 在折叠 Panel1 或 Panel2 时 最后一次的 分割像素"), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public int LastSplitterDistance
        {
            get { return m_LastSplitterDistance; }
            set
            {
                m_LastSplitterDistance = value;
                this.Invalidate();
            }
        }
        /// <summary>
        /// 
        /// </summary>
        [CategorySkinTheme, Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Localizable(false)]
        protected override bool AlwaysShowSplitter
        {
            get { return true; }
        }

        /// <summary>
        /// 获取或设置控件的背景色。
        /// </summary>
        [CategorySkinTheme, DefaultValue(typeof(Color), "Transparent")]
        public override Color BackColor
        {
            get { return base.BackColor; }
            set { var color = base.BackColor; /*if (value.A < 255) { value = Color.FromArgb(255, value.R, value.G, value.B); }*/ if (color.A != value.A || color.R != value.R || color.G != value.G || color.B != value.B) { base.BackColor = value; this.Invalidate(); } } 
        }

        #endregion


        #region  函 数 改 写


        /// <summary>
        /// 引发 System.Windows.Forms.Control.Paint 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.Windows.Forms.PaintEventArgs。</param>
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            try
            {
                base.OnPaint(e);
                //this.ResetRect();
            }
            catch (Exception ex) { Tools.LogWarn2(ex, "改写 SplitControl.OnPaint(PaintEventArgs e) 发生错误"); }
        }

        /// <summary>
        /// 引发 System.Windows.Forms.Control.MouseMove 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.Windows.Forms.MouseEventArgs。</param>
        protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button != System.Windows.Forms.MouseButtons.None)
            {
                //如果鼠标在按下状态, 即为 拖拽 状态
                mouseHoverRectType = Splitter.SplitPartType.None; //拖拽状态时, 无悬浮状态
                Rectangle rectSpliter = RectSpliter;
                this.Invalidate(rectSpliter);
                base.OnMouseMove(e);
            }
            else
            {
                Point ctrlPoint = e.Location;
                //Point ctrlPoint = Win32API.GetMouseCtrlPoint(this);
                Rectangle rectTLButton = RectTLButton;
                Rectangle rectBRButton = RectBRButton;
                Rectangle rectSpliter = RectSpliter;

                if (rectTLButton.Contains(ctrlPoint))
                {
                    mouseHoverRectType = Splitter.SplitPartType.TLButton;

                    if (TLButtonVisible || BRButtonVisible) //如果启用 折叠按钮
                        SetCursor(System.Windows.Forms.Cursors.Hand);
                    else
                        base.OnMouseMove(e);
                }
                else if (rectBRButton.Contains(ctrlPoint))
                {
                    mouseHoverRectType = Splitter.SplitPartType.BRButton;

                    if (TLButtonVisible || BRButtonVisible) //如果启用 折叠按钮
                        SetCursor(System.Windows.Forms.Cursors.Hand);
                    else
                        base.OnMouseMove(e);
                }
                else if (rectSpliter.Contains(ctrlPoint))
                {
                    //SetCursor(Cursors.Default);
                    System.Windows.Forms.Cursor cursor = (this.Orientation == System.Windows.Forms.Orientation.Horizontal) ? System.Windows.Forms.Cursors.HSplit : System.Windows.Forms.Cursors.VSplit;
                    //if (!m_IsPanel1Expanded || !m_IsPanel2Expanded) cursor = Cursors.Default; //最好是 显示箭头光标
                    SetCursor(cursor);
                    mouseHoverRectType = Splitter.SplitPartType.Spliter;
                    base.OnMouseMove(e);
                }
                else
                {
                    SetCursor(System.Windows.Forms.Cursors.Default);
                    mouseHoverRectType = Splitter.SplitPartType.None;
                    base.OnMouseMove(e);
                }

                this.Invalidate(rectSpliter);
            }

        }
        /// <summary>
        /// 引发 System.Windows.Forms.Control.MouseLeave 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.EventArgs。</param>
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);

            SetCursor(System.Windows.Forms.Cursors.Default);
            if (MouseButtons == System.Windows.Forms.MouseButtons.None)
            {
                mouseHoverRectType = Splitter.SplitPartType.None;
                Rectangle rectSpliter = RectSpliter;
                this.Invalidate(rectSpliter);
            }
        }
        /// <summary>
        /// 引发 System.Windows.Forms.Control.MouseDown 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.Windows.Forms.MouseEventArgs。</param>
        protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
        {
            Rectangle rectTLButton = RectTLButton;
            Rectangle rectBRButton = RectBRButton;
            Rectangle rectSpliter = RectSpliter;
            Point ctrlPoint = e.Location;

            if (rectTLButton.Contains(ctrlPoint))
            {
                mouseDownRectType = Splitter.SplitPartType.TLButton;
                if (!TLButtonVisible && !BRButtonVisible) base.OnMouseDown(e);
            }
            else if (rectBRButton.Contains(ctrlPoint))
            {
                mouseDownRectType = Splitter.SplitPartType.BRButton;
                if (!TLButtonVisible && !BRButtonVisible) base.OnMouseDown(e);
            }
            else if (rectSpliter.Contains(ctrlPoint))
            {
                mouseDownRectType = Splitter.SplitPartType.Spliter;
                if (Panel1Expanded && Panel2Expanded) base.OnMouseDown(e);
            }
            else
            {
                mouseDownRectType = Splitter.SplitPartType.None;
                base.OnMouseDown(e);
            }

            this.Invalidate(rectSpliter);
        }
        /// <summary>
        /// 引发 System.Windows.Forms.Control.MouseUp 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.Windows.Forms.MouseEventArgs。</param>
        protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e)
        {
            base.OnMouseUp(e);

            Rectangle rectTLButton = RectTLButton;
            Rectangle rectBRButton = RectBRButton;
            Rectangle rectSpliter = RectSpliter;
            Point ctrlPoint = e.Location;
            //Point ctrlPoint = Win32API.GetMouseCtrlPoint(this);

            //触发事件
            if (mouseDownRectType == Splitter.SplitPartType.TLButton && e.Button == System.Windows.Forms.MouseButtons.Left && rectTLButton.Contains(ctrlPoint))
                OnTLButtonClick(EventArgs.Empty);
            if (mouseDownRectType == Splitter.SplitPartType.BRButton && e.Button == System.Windows.Forms.MouseButtons.Left && rectBRButton.Contains(ctrlPoint))
                OnBRButtonClick(EventArgs.Empty);

            mouseDownRectType = Splitter.SplitPartType.None;
            this.Invalidate(rectSpliter);
        }
        /// <summary>
        /// 引发 System.Windows.Forms.Control.KeyUp 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.Windows.Forms.KeyEventArgs。</param>
        protected override void OnKeyUp(System.Windows.Forms.KeyEventArgs e)
        {
            base.OnKeyUp(e);
            Rectangle rectSpliter = RectSpliter;
            this.Invalidate(rectSpliter);
        }


        /// <summary>
        /// 引发 System.Windows.Forms.Control.HandleCreated 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.EventArgs。</param>
        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
        }
        /// <summary>
        /// 释放由 System.Windows.Forms.Control 和它的子控件占用的非托管资源，另外还可以释放托管资源。
        /// </summary>
        /// <param name="disposing">为 true 则释放托管资源和非托管资源；为 false 则仅释放非托管资源。</param>
        protected override void Dispose(bool disposing)
        {
            try
            {
                base.Dispose(disposing);
            }
            catch (Exception ex) { Tools.LogWarn2(ex, "可忽略的偶发错误"); }
        }
        /// <summary>
        /// 引发 System.Windows.Forms.Control.GotFocus 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.EventArgs。</param>
        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);
        }
        /// <summary>
        /// 引发 System.Windows.Forms.Control.LostFocus 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.EventArgs。</param>
        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);
        }

        #endregion


        #region  控 件 区 域

        /// <summary>
        /// 内部字段
        /// </summary>
        protected Rectangle m_FullRect = Rectangle.Empty;
        /// <summary>
        /// 内部字段
        /// </summary>
        protected Rectangle m_RectTLButton = Rectangle.Empty;
        /// <summary>
        /// 内部字段
        /// </summary>
        protected Rectangle m_RectBRButton = Rectangle.Empty;
        /// <summary>
        /// 内部字段
        /// </summary>
        protected Rectangle m_RectHand1 = Rectangle.Empty;
        /// <summary>
        /// 内部字段
        /// </summary>
        protected Rectangle m_RectHand2 = Rectangle.Empty;
        /// <summary>
        /// 内部字段
        /// </summary>
        protected Rectangle m_RectSpliter = Rectangle.Empty;


        /// <summary>
        /// 
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Always)]
        public Rectangle FullRect
        {
            get { return m_FullRect; }
        }
        /// <summary>
        /// 
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Always)]
        public virtual Rectangle RectTLButton
        {
            get { return m_RectTLButton; }
        }
        /// <summary>
        /// 
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Always)]
        public virtual Rectangle RectBRButton
        {
            get { return m_RectBRButton; }
        }
        /// <summary>
        /// 
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Always)]
        public virtual Rectangle RectHand1
        {
            get { return m_RectHand1; }

        }
        /// <summary>
        /// 
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Always)]
        public virtual Rectangle RectHand2
        {
            get { return m_RectHand2; }
        }
        /// <summary>
        /// 
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Always)]
        public virtual Rectangle RectSpliter
        {
            get { return m_RectSpliter; }
        }



        /// <summary>
        /// 重新计算 各种区域边界
        /// </summary>
        public override void ResetRect()
        {
            base.ResetRect();
            m_FullRect = new Rectangle(0, 0, this.Width, this.Height); //this.Location, this.Size
            m_RectSpliter = base.SplitterRectangle;

            var panel1Expanded = this.Panel1Expanded;
            var panel2Expanded = this.Panel2Expanded;
            bool isHorizontal = this.Orientation == System.Windows.Forms.Orientation.Horizontal;
            m_RectHand1 = Rectangle.Empty;
            m_RectHand2 = Rectangle.Empty;
        }


        #endregion


        #region  其 他 函 数

        /// <summary>
        /// 
        /// </summary>
        /// <param name="e">Type: EventArgs</param>
        protected virtual void OnTLButtonClick(EventArgs e)
        {
            if (!Panel1Expanded) return;

            if (!Panel2Expanded)
            {
                base.Panel1Collapsed = false;
                base.Panel2Collapsed = false;
            }
            else
            {
                base.Panel2Collapsed = false;
                base.Panel1Collapsed = true;
            }

            EventHandler handler = base.Events[m_TLButtonClickEvent] as EventHandler;
            if (handler != null) handler(this, e);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="e">Type: EventArgs</param>
        protected virtual void OnBRButtonClick(EventArgs e)
        {
            if (!Panel2Expanded) return;

            if (!Panel1Expanded)
            {
                base.Panel1Collapsed = false;
                base.Panel2Collapsed = false;
            }
            else
            {
                base.Panel1Collapsed = false;
                base.Panel2Collapsed = true;
            }

            EventHandler handler = base.Events[m_BRButtonClickEvent] as EventHandler;
            if (handler != null) handler(this, e);
        }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="e">Type: PaintEventArgs</param>
        public override void OnPaintSplitter(PaintEventArgs e)
        {
            //base.OnPaintSplitterBack(e); //不适用基类的 Splitter 绘制
        }


        #endregion
    }

}
